/**
 * description:webpack基础配置文件
 * author:
 * date:2020/04/01
 * */
const merge = require('webpack-merge');
const fs = require("fs");
const utils = require("./utils");
const config = require("./config");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const CopyWebpackPlugin = require("copy-webpack-plugin");
const VueLoaderPlugin = require('vue-loader/lib/plugin');
// const PurifyCssPlugin = require('purifycss-webpack');// css Tree Shaking
// const glob = require('glob-all');
const dllReferenceWebpack = require('./webpack.config.dll.reference');
/* isSingleEntry——单入口,viewSubDirs——多入口的文件名 */
let isSingleEntry = true, viewsSubDirs = [], purifyCssArr = [];


function getEntries() {
    let entries = {};
    try {
        /* 单入口、单页面情况 */
        fs.readFileSync(utils.resolve(`${config.entryDir}/${config.entryJsFileName}`));
        entries["index"] = utils.resolve(`${config.entryDir}/${config.entryJsFileName}`);
    } catch (err) {
        /* 多入口、多页面情况 */
        isSingleEntry = false;
        viewsSubDirs = fs.readdirSync(utils.resolve(config.entryDir));
        for (let name of viewsSubDirs) {
            entries[name] = [`${config.entryDir}/${name}/${config.entryJsFileName}`];
            purifyCssArr.push(`${config.entryDir}/${name}/App.vue`);
        }
    }
    return entries;
}

function generatorHtml() {
    let htmlArr = [];
    if (isSingleEntry) {
        htmlArr.push(new HtmlWebpackPlugin({
            filename: `./${config.entryHtmlFileName}`, //由output.path作为基路径
            template: config.htmlDir,
            chunks: ["index"], //需要引入的chunk，不配置就会引入所有页面的资源，即output输出文件名。注入路径依赖于output.publicPath/output.filename
            inject: true,
            favicon: config.faviconDir, // 页签图标
            // minify在mode为production时，默认为true，否则为false
            minify: true
        }));
    } else {
        for (let subDirName of viewsSubDirs) {
            htmlArr.push(new HtmlWebpackPlugin({
                filename: `./${subDirName}/${config.entryHtmlFileName}`, //由output.path作为基路径
                template: config.htmlDir,
                chunks: [subDirName], //需要引入的chunk，不配置就会引入所有页面的资源，即output输出文件名。注入路径依赖于output.publicPath/output.filename
                inject: true,
                favicon: config.faviconDir, // 页签图标
                // minify在mode为production时，默认为true，否则为false
                minify: true
            }));
        }
    }
    return htmlArr;
}

module.exports = merge({
    context: __dirname,
    entry: getEntries(),
    output: {
        path: config.outputRoot,
        filename: isSingleEntry ? utils.assetsPath("js/[name].js") : utils.assetsPath("[name]/js/[name].js"),
        chunkFilename: utils.assetsPath(`${config.toStaticPath}/js/[name].js`), // 非入口js模块，命名规则[name]_[chunkhash].js
        publicPath: config.assetsPublicPath// 静态资源引用路径
    },
    module: {
        noParse: [/jquery/],
        rules: [
            /*{
                test:/\.(js|vue)$/,
                loader:"eslint-loader",
                enforce:'pre',
                include:[utils.resolve('server'),utils.resolve('client/assets/js'),utils.resolve('client/views')],
                exclude: [utils.resolve('node_modules'),utils.resolve('server/node_modules'),utils.resolve(config.outputRoot)],
                options: {
                    formatter: require('eslint-friendly-formatter')
                }
            },*/
            {
                test: /\.(js|jsx|es)?$/,
                use: 'babel-loader',
                include: [utils.resolve('client'), utils.resolve('node_modules/element-ui/packages')],
            }, {
                test: /\.vue$/,
                include: [utils.resolve('client'), utils.resolve('node_modules/element-ui/packages')],
                use: ['vue-loader'], // vue-loader 15.X后不支持使用happypack插件
            },
            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    esModule: false, // 防止img路径变为[object Module]
                    useRelativePath: false,
                    outputPath: `${config.toStaticPath}/images/`,
                    // publicPath:'/',// 配置不同静态资源存不同CDN时使用
                    name: "[name].[hash:7].[ext]"
                }
            },
            {
                test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    esModule: false, // 防止img路径变为[object Module]
                    useRelativePath: false,
                    outputPath: `${config.toStaticPath}/medias/`,
                    name: '[name].[hash:7].[ext]'
                }
            },
            {
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    esModule: false, // 防止img路径变为[object Module]
                    useRelativePath: false,
                    outputPath: `${config.toStaticPath}/fonts/`,
                    name: '[name].[hash:7].[ext]'
                }
            }
        ]
    },
    resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
            '@': utils.resolve('client'),
            vue: 'vue/dist/vue.esm.js'
        }
        /* // 不能与DllReferencePlugin一起设置
		modules: [resolve("node_modules")],
		mainFields: ['index', 'main'],*/
    },
    optimization: {
        //parent chunk中解决了的chunk会被删除
        removeAvailableModules: true,
        //删除空的chunks
        removeEmptyChunks: true,
        //合并重复的chunk
        mergeDuplicateChunks: true
    },
    plugins: [
        ...generatorHtml(),
        new VueLoaderPlugin(),
        // new PurifyCssPlugin({paths: glob.sync(purifyCssArr)}),
        new CleanWebpackPlugin(), // 默认清空我们output里面设置的所有文件夹
        /* copy from static to new path */
        new CopyWebpackPlugin([
            {
                from: utils.resolve(config.fromStaticPath),
                to: config.toStaticPath,
                ignore: ['.*']
            }
        ])
    ]
}, dllReferenceWebpack);
